﻿///<copyright>
/// Copyright © 2009 Stephen Styrchak. All Rights Reserved.
///</copyright>
using System;
using System.ComponentModel;
using Ferpect.ComponentModel.Design;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
#if WINDOWS
using System.ComponentModel.Design;
#endif

namespace Ferpect.ComponentModel.Sprites
{
    [Description("Draws a Texture2D image.")]
#if WINDOWS
    [Designer(Designers.ImageSpriteDesigner, typeof(IDesigner))]
#endif
    public class ImageSprite : Sprite
    {
        private Texture2D texture;
        private string textureName;
        private Rectangle? fullScreen;
        private Rectangle? sourceRectangle;

        public ImageSprite()
        {
        }

        [Category("Layout")]
        [DefaultValue(false)]
        [RefreshProperties(RefreshProperties.All)]
        public bool FullScreen
        {
            get
            {
                return this.fullScreen.HasValue;
            }
            set
            {
                if (!value)
                {
                    if (this.fullScreen.HasValue)
                    {
                        this.fullScreen = null;
                    }
                }
                else
                {
                    if (!this.fullScreen.HasValue)
                    {
                        this.Position = new Vector2();
                        this.RelativeOrigin = RelativeLocation.TopLeft;
                        this.Origin = new Vector2();
                        this.Scale = 1f;
                    }
                    this.SetFullScreen();
                }
            }
        }

        [Category("Appearance")]
        [DefaultValue(null)]
        public Rectangle? SourceRectangle
        {
            get
            {
                return this.sourceRectangle;
            }
            set
            {
                if (value.HasValue)
                {
                    Rectangle fullSize = new Rectangle();
                    fullSize.Width = this.texture.Width;
                    fullSize.Height = this.texture.Height;
                    bool contained;
                    fullSize.Contains(ref fullSize, out contained);
                    if (!contained)
                    {
                        throw new ArgumentException("The specified source rectangle exceeds the bounds of the texture.");
                    }
                }
                this.sourceRectangle = value;
                this.ResetRelativeOrigin();
            }
        }

        [Category("Appearance")]
        [TypeConverter(TypeConverters.Texture2DConverter)]
        [RefreshContent()]
        public string TextureName
        {
            get
            {
                return this.textureName;
            }
            set
            {
                this.textureName = value;
            }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Texture2D Texture
        {
            get
            {
                return texture;
            }
        }

        public override void LoadContent(ContentManager content)
        {
            if (content == null) throw new ArgumentNullException("content");

            if (!String.IsNullOrEmpty(this.textureName))
            {
                this.texture = content.Load<Texture2D>(this.textureName);
            }
            if (this.fullScreen.HasValue)
            {
                this.SetFullScreen();
            }
            this.ResetRelativeOrigin();
        }

        private void SetFullScreen()
        {
            IViewportService viewport = (IViewportService)this.GetService(typeof(IViewportService));
            if (viewport != null)
            {
                if (this.UseTitleSafeArea)
                {
                    this.fullScreen = viewport.TitleSafeArea;
                }
                else
                {
                    this.fullScreen = viewport.ViewportArea;
                }
                return;
            }
            this.fullScreen = new Rectangle();
        }

        public override void UnloadContent()
        {
            this.texture = null;
        }

        public override void Draw(SpriteBatchStack spriteBatchStack)
        {
            if (spriteBatchStack == null) throw new ArgumentNullException("spriteBatchStack");

            if (this.texture != null && this.Visible)
            {
                if (this.fullScreen.HasValue)
                {
                    spriteBatchStack.Current.Draw(this.texture, this.fullScreen.Value, this.SourceRectangle, this.Color, 0, Vector2.Zero, this.Effects, this.LayerDepth);
                }
                else
                {
                    spriteBatchStack.Current.Draw(this.texture, this.Position, this.SourceRectangle, this.Color, this.Rotation, this.Origin, this.Scale, this.Effects, this.LayerDepth);
                }
            }
        }

        public override Vector2 GetSize()
        {
            if (this.texture != null)
            {
                if (this.fullScreen.HasValue)
                {
                    Rectangle sizeRect = this.fullScreen.Value;
                    return new Vector2(sizeRect.Width, sizeRect.Height);
                }
                if (this.sourceRectangle.HasValue)
                {
                    return new Vector2(this.sourceRectangle.Value.Width, this.sourceRectangle.Value.Height);
                }

                return new Vector2(this.texture.Width, this.texture.Height);
            }
            return new Vector2(64, 64);
        }
    }
}
